package com.katze.boot.applet.asn1.adapter;

import com.katze.boot.applet.asn1.anlysis.ASN1Analysis;
import org.bouncycastle.asn1.ASN1TaggedObject;

import java.nio.file.Files;
import java.nio.file.Path;

/**
 * asn1文件含有文件头信息
 * 1.文件头占8个字节
 * 2.话单结构：话单长度 + 占位符 + 话单内容
 */
public class ASN1ContainHeadAdapter implements BasicAdapter {

    private static ASN1ContainHeadAdapter adapter = null;
    private Path file;
    private Path output;
    private String filename;
    private int space;

    public ASN1ContainHeadAdapter() {}

    private void reset(Path file, String filename, int space, Path output) {
        this.file = file;
        this.filename = filename;
        this.space = space;
        this.output = output;
    }

    public static ASN1ContainHeadAdapter getInstance(Path file, String filename, int space, Path output) {
        if (adapter == null) adapter = new ASN1ContainHeadAdapter();
        adapter.reset(file, filename, space, output);
        return adapter;
    }

    @Override
    public void run() {
        try (ASN1Analysis analysis = new ASN1Analysis(true, "@")){
            analysis.config(this.filename).storage(output);
            byte[] data = Files.readAllBytes(file);
            int fileLength, readLength;
            byte[] bytes = new byte[4];

            System.arraycopy(data, 0, bytes, 0, bytes.length);
            fileLength = binaryToLength(bytes);

            System.arraycopy(data, 4, bytes, 0, bytes.length);
            readLength = binaryToLength(bytes);

            do {
                bytes = new byte[2];
                System.arraycopy(data, readLength, bytes, 0, bytes.length);//话单长度
                readLength += bytes.length;

                bytes = new byte[binaryToLength(bytes)];
                System.arraycopy(data, readLength += space, bytes, 0, bytes.length);//话单内容
                readLength += bytes.length;

                ASN1TaggedObject crdObject = ASN1TaggedObject.getInstance(bytes); //话单对象
                analysis.save(crdObject);
            } while (readLength < fileLength);
        } catch (Exception e){
            e.printStackTrace();
        }
    }

    private int binaryToLength(byte[] bytes) {
        int length = 0;
        for (int i = 0; i < bytes.length; i++) {
            length += (bytes[i] & 0xFF) * (Math.pow(256, bytes.length - 1 - i));
        }
        return length;
    }
}
